// Decompiled by DJ v3.9.9.91 Copyright 2005 Atanas Neshkov  Date: 10/22/2005 11:07:03 PM
// Home Page : http://members.fortunecity.com/neshkov/dj.html  - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name:   TestStep.java

package net.sf.ivyide.idea;

import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Pair;
import fr.jayasoft.ivy.ModuleId;
import net.sf.ivyide.DependencyType;
import net.sf.ivyide.ModuleManager;
import net.sf.ivyide.ModuleManagerFactory;
import net.sf.ivyide.ModuleProvider;
import net.sf.ivyide.ModuleProviderFactory;
import net.sf.ivyide.MyAntEnvironmentInfo;
import net.sf.ivyide.ResolvedModule;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

// Referenced classes of package com.ivyplugin.j2meplugin.module:
//            DependencyType, IvyModuleBuilder, IvyModuleSettings, IvyUtil

public class IvyDependenciesStep {
    private IvyProjectSettings m_settings;
    private JComboBox m_rootModuleComboBox;
    private boolean m_modified = false;
    private JButton m_environmentButton;
    private Map<ModuleId, File> m_moduleFiles;

    public IvyDependenciesStep(IvyProjectSettings settings, Project project) {
        this(project);
        m_settings = settings;
    }

    private IvyDependenciesStep(final Project project) {
        m_environmentButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                //Frame frameForComponent = JOptionPane.getFrameForComponent(IvyDependenciesStep.this.getComponent());
                // JDialog dialog = new JDialog(frameForComponent, "ping", true);
                final IvyPluginConfiguration ivyPluginConfiguration = new IvyPluginConfiguration((MyAntEnvironmentInfo) m_settings.m_environmentInfo, project);
                // dialog.getRootPane().add(ivyPluginConfiguration.getComponent());
                // dialog.setModal(true);
                // dialog.pack();        Messages.showOkCancelDialog()
                // dialog.setVisible(true);
                DialogWrapper wrapper = new DialogWrapper(IvyDependenciesStep.this.getComponent(), true) {
                    {
                        init();
                    }

                    protected JComponent createCenterPanel() {
                        return ivyPluginConfiguration.getComponent();
                    }

                    @Override
                    protected void doOKAction() {
                        Pair<ModuleProviderFactory, ModuleProvider> validInfoFromGui = ivyPluginConfiguration.getValidInfoFromGui();
                        if (validInfoFromGui != null) {
                            m_settings.m_environmentInfo = validInfoFromGui.getFirst();
                            m_moduleFiles = validInfoFromGui.getSecond().getModules();
                            super.doOKAction();
                        }
                    }

                };
                wrapper.setTitle("Ivy environment settings");
                wrapper.pack();
                wrapper.show();
                if (wrapper.isOK()) {
                    updateGuiFromBuilderSettings();
                    m_modified = true;

                }
            }
        });
    }

    public JComponent getComponent() {
        return m_panel;
    }

    private void rootModuleChanged() {
        m_modified = true;
        ProgressUtilities.executeRunnableWithProgress(new ProgressAwareRunnable() {
            public void run(ProgressIndicator indicator) {
                indicator.setIndeterminate(true);
                File rootModuleDir = getRootModuleDir();
                if (rootModuleDir != null) {
                    ModuleManager moduleManager = createModuleManagerFromGui();
                    ResolvedModule resolvedModule = moduleManager.resolveModule(rootModuleDir);
                    Map<ModuleId, DependencyType> internalModules = moduleManager.getDependantModules(resolvedModule);
                    updateModuleTable(internalModules);
                    resolvedModule.checkResolveErrors();
                }
            }
        }, "Resolving selected module...", false);
/*
        if (buffer.length() > 0) {
            JOptionPane.showMessageDialog(IvyDependenciesStep.this.m_panel, buffer.toString(), "IVY resolution error", JOptionPane.WARNING_MESSAGE);
        }
*/
/*
        StringBuffer warningMessage = ProgressUtilities.executeRunnableWithProgress(IvyDependenciesStep.this.m_panel, "Resolving selected module...", "Unable to get project list", new Callable<StringBuffer>() {

            public StringBuffer call() throws Exception {
                IvyProjectSettings settings = getSettings();
                if (settings.m_rootModuleDir != null) {
                    IvyResolvedModule resolvedModule = new IvyResolvedModule(settings);
                    ResolveReport report = resolvedModule.getReport();
                    StringBuffer buffer = null;
                    if (report.hasError()) {
                        buffer = new StringBuffer("Errors occured during resolution of component " + settings.m_rootModuleDir + "\n");
                        if (report.getUnresolvedDependencies().length > 0) {
                            IvyNode[] unresolvedDependencies = report.getUnresolvedDependencies();
                            buffer.append("\n");
                            buffer.append(unresolvedDependencies.length > 1 ? "Unresolved dependencies:\n" : "Unresolved dependency:\n");
                            for (IvyNode unresolvedDependency : unresolvedDependencies) {
                                buffer.append(unresolvedDependency).append("\n");
                            }
                        }
                        buffer.append("\nMake sure the project can be resolved in order to get all depenencies.");
                    }
                    Map<ModuleId, DependencyType> internalModules = resolvedModule.getInternalModules();
                    updateModuleTable(internalModules);
                    return buffer;
                }
                return null;
            }

        });
        if (warningMessage != null) {
            JOptionPane.showMessageDialog(IvyDependenciesStep.this.m_panel, warningMessage, "IVY resolution error", JOptionPane.WARNING_MESSAGE);
        }
*/
    }

    private void updateModuleTable(Map<ModuleId, DependencyType> internalModules) {
        m_modulesTable.setEnabled(true);
        List<ModuleId> moduleIds = new LinkedList<ModuleId>(internalModules.keySet());
        DefaultTableModel tableModel = new DefaultTableModel() {

            public boolean isCellEditable(int i, int i1) {
                return i1 != 0;
            }

            public void setValueAt(Object object, int i, int i1) {
                m_modified = true;
                super.setValueAt(object, i, i1);
            }

        };
        Collections.sort(moduleIds, new Comparator<ModuleId>() {
            public int compare(ModuleId moduleId, ModuleId moduleId1) {
                return moduleId.getName().compareTo(moduleId1.getName());
            }
        });
        tableModel.addColumn("Module Name", moduleIds.toArray());
        List<Boolean> types = new LinkedList<Boolean>();
        for (ModuleId moduleId : moduleIds) {
            types.add(internalModules.get(moduleId).equals(DependencyType.SOURCE));
        }

        tableModel.addColumn("Include source", types.toArray());
        m_modulesTable.setModel(tableModel);
        TableColumn moduleColumn = m_modulesTable.getColumnModel().getColumn(0);
        moduleColumn.setHeaderValue("Module Name");
        TableColumn column = m_modulesTable.getColumnModel().getColumn(1);
        column.setHeaderValue("Include Source");
        column.setCellEditor(m_modulesTable.getDefaultEditor(Boolean.class));
        column.setCellRenderer(m_modulesTable.getDefaultRenderer(Boolean.class));
    }

    private Map<ModuleId, File> getAllModules(final ModuleProviderFactory factory) {
        if (m_moduleFiles == null) {
            //this should only happen the first time a project is loaded.
            //alternatively, we could store the paths in the project file as well..
            ProgressUtilities.executeRunnableWithProgress(new ProgressAwareRunnable() {
                public void run(ProgressIndicator indicator) {
                    indicator.setIndeterminate(true);
                    m_moduleFiles = factory.createModuleProvider().getModules();
                }
            }, "Discovering root modules...", false);
        }
        return m_moduleFiles;
    }

    public ModuleManagerFactory createModuleManagerFactory(final IvyProjectSettings settings) {
        return new ModuleManagerFactory() {
            public ModuleManager createModuleManager() {
                return IvyDependenciesStep.this.createModuleManagerFromSettings(settings);
            }
        };
    }

    private ModuleManager createModuleManagerFromGui() {
        return new ModuleManager(m_settings.m_environmentInfo.createModuleProvider(), createModuleDependencies(), getRootModuleDir());
    }

    private ModuleManager createModuleManagerFromSettings(IvyProjectSettings settings) {
        ModuleManager moduleManager = new ModuleManager(settings.m_environmentInfo.createModuleProvider(), settings.m_moduleDependencies, settings.m_rootModuleDir);
        m_moduleFiles = moduleManager.getModules();//hack always keep track of latest modules..
        return moduleManager;
    }

    void updateGuiFromBuilderSettings() {
        m_modified = false;
        if (m_settings.m_environmentInfo != null) {
            Map<ModuleId, File> modules = getAllModules(m_settings.m_environmentInfo);

            ActionListener[] actionListeners = m_rootModuleComboBox.getActionListeners();
            for (ActionListener actionListener : actionListeners) {
                m_rootModuleComboBox.removeActionListener(actionListener);
            }
            m_rootModuleComboBox.setModel(new DefaultComboBoxModel(new LinkedList<File>(modules.values()).toArray()));
            if (m_settings.m_rootModuleDir != null) {
                //if no rootmodule specified yet, the module dependencies should be ignored (they will be empty anyway)
                //instead, keep the table as it currently is..
                m_rootModuleComboBox.setSelectedItem(m_settings.m_rootModuleDir);
                updateModuleTable(m_settings.m_moduleDependencies);
            } else {
                m_rootModuleComboBox.setSelectedItem(null);
                updateModuleTable(new LinkedHashMap<ModuleId, DependencyType>());
            }
            //only add this listener after the gui has been updated. The listener should only be called on interactive change
            m_rootModuleComboBox.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent actionEvent) {
                    rootModuleChanged();
                }
            });
            m_panel.revalidate();
            //only way to force a resize of the window (if too many options in drop down list..)
            SwingUtilities.windowForComponent(m_panel).pack();
        }
    }

    private File getRootModuleDir() {
        return (File) m_rootModuleComboBox.getSelectedItem();
    }

    public boolean isModified() {
        return m_modified;
    }

    public void setModified(boolean modified) {
        m_modified = modified;
    }

    void updateBuilderSettingsFromGui() {
        m_settings.m_rootModuleDir = (File) m_rootModuleComboBox.getSelectedItem();
        m_settings.m_moduleDependencies = createModuleDependencies();
    }

    private Map<ModuleId, DependencyType> createModuleDependencies() {
        Map<ModuleId, DependencyType> dependencies = new LinkedHashMap<ModuleId, DependencyType>();
        TableModel model = m_modulesTable.getModel();
        for (int i = 0; i < model.getRowCount(); i++) {
            ModuleId moduleId = (ModuleId) model.getValueAt(i, 0);
            Boolean source = (Boolean) model.getValueAt(i, 1);
            dependencies.put(moduleId, source ? DependencyType.SOURCE : DependencyType.LIBRARY);
        }
        return dependencies;
    }

    private JPanel m_panel;
    private JTable m_modulesTable;

}